package ar.edu.itba.it.cg.grupo01.impl.scene.optimization;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Collection;

import ar.edu.itba.it.cg.grupo01.api.Intersectable;
import ar.edu.itba.it.cg.grupo01.api.Intersection;
import ar.edu.itba.it.cg.grupo01.api.Ray;
import ar.edu.itba.it.cg.grupo01.api.shape.Shape;
import ar.edu.itba.it.cg.grupo01.impl.IntersectionFactory;
import ar.edu.itba.it.cg.grupo01.impl.shape.AABB;

abstract class OctNode implements Intersectable {

	protected AABB box;
	protected IntersectionFactory intersectionFactory;
	
	
	OctNode(AABB box, IntersectionFactory intersectionFactory) {
		checkNotNull(box, "Box should not be null");
		checkNotNull(intersectionFactory, "IntersectionFactory should not be null");
		this.box = box;
		this.intersectionFactory = intersectionFactory;
	}
	
	static OctNode of(Collection<? extends Shape> shapes, AABB box, int shapesPerNode, int maxDepth, IntersectionFactory intersectionFactory) {
		
		if( maxDepth == 0 ) {
			return new Leaf(shapes, box, intersectionFactory);
		}
		return shapes.size() <= shapesPerNode ? new Leaf(shapes,box, intersectionFactory) : new Internal(shapes,box,shapesPerNode, maxDepth, intersectionFactory);
	}

	abstract public int getDepth();

	abstract int leafAmount();

	public abstract Intersection<? extends Shape> hitsLight(Ray lightRay, Shape shape);
	
}
